﻿#include "pinpointhandle.h"
#include <QPainter>
#include <QDebug>
#include "drawobj.h"

PinPointHandleGroup::PinPointHandleGroup(const Unit &unit, QGraphicsItem* parent)
{
    for (const Pin& pin : unit.inputPins)
        addPinByDirection(pin, parent);
    for (const Pin& pin : unit.outputPins)
        addPinByDirection(pin, parent);
}

PinPointHandleGroup::~PinPointHandleGroup()
{
}


void PinPointHandleGroup::addPinByDirection(const Pin &pin,QGraphicsItem *parent)
{
    switch (DirectionConverter::toDirection(pin.dir))
    {
        case Direction::Left:
            leftPins.append(new PinPointHandle(pin, parent));
            break;
        case Direction::Right:
            rightPins.append(new PinPointHandle(pin, parent));
            break;
        case Direction::Up:
            upPins.append(new PinPointHandle(pin,parent));
            break;
        case Direction::Down:
            downPins.append(new PinPointHandle(pin, parent));
            break;
    }
}

void PinPointHandleGroup::movePins(Direction dir, QRectF rect)
{
    QList<PinPointHandle*> handles = getPins(dir);
    int size = handles.size();

    int index = 0;
    switch (dir)
    {
        case Direction::Right:
        {
            for(auto it : handles)
                it->move(rect.x() + rect.width(), rect.y() + rect.height() / (size +1) * ++index);
            break;
        }
        case Direction::Down:
        {
            for(auto it : handles)
                it->move(rect.x() + rect.width()/(size +1) * ++index, rect.y());
            break;
        }
        case Direction::Left:
        {
            for(auto it : handles)
                it->move(rect.x(), rect.y() + rect.height() / (size +1) * ++index);
            break;
        }
        case Direction::Up:
        {
            for(auto it : handles)
                it->move(rect.x() + rect.width()/(size +1) * ++index, rect.y() + rect.height());
            break;
        }
    }
    for(auto it:handles)
        it->show();
}

PinPointHandle *PinPointHandleGroup::getClickPin(const QPointF& pos)
{
    QList<PinPointHandle*> alltHandles;
    alltHandles.append(leftPins);
    alltHandles.append(rightPins);
    alltHandles.append(upPins);
    alltHandles.append(downPins);

    for(auto handle : alltHandles)
    {
        if(handle->contains(handle->mapFromScene(pos)))
            return handle;
    }
    return nullptr;
}

PinPointHandle *PinPointHandleGroup::getPinFormPinIndex(int index)
{
    QList<PinPointHandle*> alltHandles;
    alltHandles.append(leftPins);
    alltHandles.append(rightPins);
    alltHandles.append(upPins);
    alltHandles.append(downPins);

    for(auto handle : alltHandles)
    {
        if(handle->getPin().index == index)
            return handle;
    }
    return nullptr;
}

const QList<PinPointHandle*>& PinPointHandleGroup::getPins(Direction dir) const
{
    switch(dir)
    {
        case Direction::Right:
            return rightPins;
        case Direction::Down:
            return downPins;
        case Direction::Left:
            return leftPins;
        case Direction::Up:
            return upPins;
    }
}

void PinPointHandleGroup::updatePinPointHandle(GraphicsRectItem *item)
{
    // 先清空列表里面的指针对象
    qDeleteAll(leftPins);
    qDeleteAll(rightPins);
    qDeleteAll(downPins);
    qDeleteAll(upPins);

    // 再重置列表大小
    leftPins.clear();
    rightPins.clear();
    downPins.clear();
    upPins.clear();

    foreach (auto pin, item->getUnit().inputPins)
        addPinByDirection(pin, item);
    foreach (auto pin, item->getUnit().outputPins)
        addPinByDirection(pin, item);
}


Direction DirectionConverter::toDirection(const QString &dirStr)
{
    static const QHash<QString, Direction> directionMap =
    {
        {"none", Direction::None},
        {"right", Direction::Right},
        {"down", Direction::Down},
        {"left", Direction::Left},
        {"up", Direction::Up},
        {"Right", Direction::Right},
        {"Down", Direction::Down},
        {"Left", Direction::Left},
        {"Up", Direction::Up}
    };
    return directionMap.value(dirStr, Direction::None); // 找不到时返回 None
}

QString DirectionConverter::toString(Direction dir)
{
    switch (dir)
    {
        case Direction::None:  return "none";
        case Direction::Right: return "right";
        case Direction::Down:  return "down";
        case Direction::Left:  return "left";
        case Direction::Up:    return "up";
        default:               return "none"; // 处理未覆盖的枚举值
    }
}


void PinPointHandle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->save();
    painter->setPen(Qt::SolidLine);
    painter->setRenderHint(QPainter::Antialiasing,false);
    painter->setPen(QPen(Qt::black,Qt::SolidLine));
    m_pin.isInputPin ? painter->setBrush(Qt::green) : painter->setBrush(Qt::red);
    painter->drawEllipse(rect().center(),5,5);
    painter->restore();
}

void PinPointHandle::move(qreal x, qreal y)
{
    setPos(x,y);
    m_pos = QPointF(x,y);
}

QRectF PinPointHandle::getParentRect() const
{
    GraphicsRectItem* item = dynamic_cast<GraphicsRectItem*>(parentItem());
    return item ? item->rect() : QRectF();
}

bool PinPointHandle::contains(const QPointF &point) const
{
    return std::abs(point.x()) < EllipseItemRadius && std::abs(point.y()) < EllipseItemRadius;
}
